
#!coding:utf-8
# vim: tabstop=4 shiftwidth=4 softtabstop=4

"""
    for testing
    @Jay.han
"""

import os
import logging
import random
import tempfile
import shutil
import contextlib
from cvirt.common import exception
LOG = logging.getLogger(__name__)

IMAGE_PATH = ''
def get_test_image_info():

    image_ref = {'id':1,
                 'name':'test',
                 'disk_format':'raw',
                 'size':1,
                 'status':"alive",
                 'owner':None,
                 'os_type':'linux',
                 'host':'127.0.0.1'}

    return image_ref




def get_test_instance():
    test_instance = {'memory_kb': '1024000',
                     'basepath': '/some/path',
                     'bridge_name': 'br100',
                     'vcpus': 2,
                     'root_gb': 10,
                     'project_id': 'fake',
                     'bridge': 'br101',
                     'image_ref': 'cedef40a-ed67-4d10-800e-17455edce175',
                     'instance_type_id': '5'}  # m1.small


    return test_instance


def get_test_network_info(count=1):
    pass

def execute(*cmd, **kwargs):
    cmd = map(str, cmd)

    print ('Running cmd (subprocess): %s' % cmd), ' '.join(cmd)

def default_uuid():
    _uuid = [ random.randint(0, 255) for dummy in range(0, 16) ]
    return "-".join(["%02x" * 4, "%02x" * 2, "%02x" * 2, "%02x" * 2,
                     "%02x" * 6]) % tuple(_uuid)



def chown(path, owner):
    execute('chown', owner, path)

def create_image(disk_format, path, size):
    execute('qemu-img', 'create', '-f', disk_format, path, size)

def create_cow_image(backing_file, path):
    execute('qemu-img', 'create', '-f', 'qcow2', '-o',
            'cluster_size=2M,backing_file=%s' % backing_file, path)

def get_disk_size(path):
    out, _ = execute('qemu-img', 'info', path)
    size = [i.split('(')[1].split()[0] for i in out.split('\n')
            if i.strip().find('virtual size') >= 0]
    return int(size[0])

def copy_file(src, dest):
    shutil.copy(src, dest)

def resize_disk(disk_path,resize_size):
    execute('qemu-img','resize',disk_path,'+'+str(resize_size)+'G')

"""
snapshot
"""

def create_snapshot(disk_path, snapshot_name):
    execute('qemu-img','snapshot','-c',snapshot_name,disk_path)

def restore_snapshot(disk_path,snapshot_name):
    execute('qemu-img','snapshot','-a',snapshot_name,disk_path)

def delete_snapshot(disk_path, snapshot_name):
    execute('qemu-img','snapshot','-d',snapshot_name,disk_path)

def extract_snapshot(disk_path, source_fmt, snapshot_name, out_path, dest_fmt):
    """Extract a named snapshot from a disk images    """
    execute('qemu-img','convert','-f',source_fmt, '-O',dest_fmt,'-s',snapshot_name,disk_path,out_path)

def create_local(target, size, unit='G'):
    execute('qemu-img', 'create', '-f', 'raw', target, '%d%c' % (size, unit))

def ensure_fold(base_path):
    if "," in base_path:
        path = base_path.split(",")
        for p in path:
            if not os.path.exists(p):
                os.makedirs(p)
    else:
        if not os.path.exists(base_path):
            os.makedirs(base_path)


"""@contextmanager decorator.

    Typical usage:

        @contextmanager
        def some_generator(<arguments>):
            <setup>
            try:
                yield <value>
            finally:
                <cleanup>

    This makes this:

        with some_generator(<arguments>) as <variable>:
            <body>

    equivalent to this:

        <setup>
        try:
            <variable> = <value>
            <body>
        finally:
            <cleanup>

    """
@contextlib.contextmanager
def tempdir(**kwargs):
    tmpdir = tempfile.mkdtemp(**kwargs)
    try:
        yield tmpdir
    finally:
        try:
            shutil.rmtree(tmpdir)
        except OSError, e:
            LOG.debug('Could not remove tmpdir: %s' % str(e))

"""
    os.umask(mask)

    Set the current numeric umask and return the previous umask.
    umask 是指 007 770 这种权限
"""
def write_to_file(path, contents,umask=None):
    if umask:
        os_xxx = os.umask(umask)
    try:
        with open(path, 'w') as f:
            f.write(contents)
    finally:
        if umask:
            os.umask(os_xxx)

def get_fs_info(path):
    """Get free/used/total space info for a filesystem

    :param path: Any dirent on the filesystem
    :returns: A dict containing:

             :free: How much space is free (in bytes)
             :used: How much space is used (in bytes)
             :total: How big the filesystem is (in bytes)
    """
    total = 0
    free = 0
    used = 0
    if ',' in path:
        path_list =  path.split(',')
        for _path in path_list:
            hddinfo = os.statvfs(_path)
            total += hddinfo.f_frsize * hddinfo.f_blocks
            free += hddinfo.f_frsize * hddinfo.f_bavail
            used += hddinfo.f_frsize * (hddinfo.f_blocks - hddinfo.f_bfree)
    else:
        hddinfo = os.statvfs(path)
        total = hddinfo.f_frsize * hddinfo.f_blocks
        free = hddinfo.f_frsize * hddinfo.f_bavail
        used = hddinfo.f_frsize * (hddinfo.f_blocks - hddinfo.f_bfree)
    return {'total': total,
            'free': free,
            'used': used}


def get_instance_path(instances_path,existed_vms=0):
    if ',' in instances_path:
        path_list = instances_path.split(',')
        num = existed_vms % len(path_list)
        return path_list[num]
    else:
        return instances_path

def copy_image(src, dest, host=None):
    """Copy a disk image to an existing directory
    """
    if not host:
        execute('cp', src, dest)
    else:
        dest = "%s:%s" % (host, dest)
        try:
            execute('rsync', '--sparse', '--compress', '--dry-run', src, dest)
        except exception.ProcessExecutionError:
            execute('scp', src, dest)
        else:
            execute('rsync', '--sparse', '--compress', src, dest)

def cache_base_image(instances_path,image,existed_vms=0):

    num = 0
    image_path = None
    if ',' in instances_path:
        has_base_img = False

        path_list = instances_path.split(',')
        image_path_list = []
        # if has image id then cache it
        if 'id' in image:
            for p in path_list:
                _base_path = os.path.join(p, '_base')
                ensure_fold(_base_path)
                base_img = os.path.join(_base_path, '%s.base' % image['imageid'])
                if not os.path.exists(base_img):
                    if has_base_img:
                        LOG.info("copying image %s to %s" % (image['imageid'],base_img))
                        copy_file(image_path_list.pop(),base_img)
                    else:
                        LOG.info("Dowloading image %s." % image['imageid'])
                        copy_image(IMAGE_PATH+"/"+image['imageid'],base_img)
                        LOG.info("Complete dowloading image %s." % image['imageid'])

                has_base_img = True
                image_path_list.append(base_img)

            num = existed_vms % len(image_path_list)
            image_path = image_path_list[num]

        return image_path,path_list[num]
    else:
        base_path = os.path.join(instances_path, '_base')
        ensure_fold(base_path)
        if 'id' in image:
            image_path = os.path.join(base_path, '%s.base' % image['imageid'])
            if not os.path.exists(image_path):
                LOG.info("Dowloading image %s." % image['imageid'])

                copy_image(IMAGE_PATH+"/"+image['imageid'],image_path)
                #image_client.download(base_img, image)
                LOG.info("Complete dowloading image %s." % image['imageid'])

        return image_path,instances_path


def vdisk_info(diskpath):
    return dict(base='ubuntu.img',size=20,realsize="800M",format="qcow2")


def get_hostname():
    return 'simbas-pc'
